#include "stdafx.h"
#include "SerialPort.h"
#include "MyThread.h"


MyThread::MyThread(void)
{
	stop=false;
}

MyThread::MyThread(QTableWidget *toUpdate)
{
	stop=false;
	tabTransact=toUpdate;
}
MyThread::~MyThread(void)
{
}

void MyThread::Initialize()
{
	to_PriceDisplay = false;
	pID=1;
}
void MyThread::run()
{
	Initialize();
	int k=0;
	wchar_t *device=L"COM5";
	SerialPort *serial=new SerialPort();
	char buffer_send[128];
	char buffer[128];
	char line0_chr[41];
	char line1_chr[18];
	string intepret_Res;
	string name;
	serial->connect(device);
	Hardware_handling *Handling= new Hardware_handling();
	while (1)
	{
		QMutex mutex;
		mutex.lock();

		size_t len_buf=serial->getArray(buffer, 128);
		int s=0;
		if (len_buf)
		{
			unsigned int start = ::GetTickCount();
			Handling->set_cmd(buffer,len_buf);
			intepret_Res=Handling->Intepret();
			//intepret_Res=Intepret(buffer,len_buf);

			if (intepret_Res.size())
			{
				memcpy(buffer_send,intepret_Res.c_str(),intepret_Res.size());
				buffer_send[intepret_Res.size()]=0;
				size_t len = strlen(buffer_send);
				len=serial->sendArray(buffer_send, len);
			}
			
			k=1-k;
			//emit NumberChanged(k);
			printf("Program took: %f seconds\n", (::GetTickCount() - start) * .001);
		}	
		
		if (to_PriceDisplay)
		{
			// Information for price display
			string line0="";
			string line1="";

			if (pID)
			{
				line0=Handling->to_Price_display(pID);
				// Send to serial if pId exists
				if (line0!="")
				{
					memcpy(line0_chr,line0.c_str(),line0.size());
					line0_chr[line0.size()]=0;
					size_t len_pId=strlen(line0_chr);
					len_pId=serial->sendArray(line0_chr,len_pId);
				}
			}
			else
			{
				int i;
				int size=getTotalPID();
				string lin="";
				for (i=1;i<=PID_SIZE;i++)
				{
					line0=Handling->to_Price_display(i);

					// Send to serial if pId exists
					if (line0!="")
					{
						memcpy(line0_chr,line0.c_str(),line0.size());
						line0_chr[line0.size()]=0;
						size_t len_pId=strlen(line0_chr);
						len_pId=serial->sendArray(line0_chr,len_pId);
					}
				}


			}
		}
		
		to_PriceDisplay=false;
		mutex.unlock();	
		this->sleep(1);
	}
	serial->disconnect();
	delete serial;
	delete Handling;

}

int MyThread::getTotalPID()
{
	int result=0;
	sql_Connector *contor=new sql_Connector();
	contor->start_Connect();
	contor->chooseDB(LOCAL_DB);
	result=contor->getTotal_PriceDisplay();
	delete contor;
	return result;
}

void MyThread::clearTransactList()
{
	iList.clear();
}

void MyThread::getTransactList(vector<Transaction *> &iGet)
{
	QMutex mutex;
	mutex.lock();
	iGet=iList;
	mutex.unlock();
}

/*
	Intepret the command frame
*/
string MyThread::Intepret(char buffer[],size_t len_buf)
{
	string buffer_res="";
	unsigned char cmd;
	// Skip firsts 2 byte of cashierID, read the command
	cmd=buffer[2]-'0';
	switch(cmd)
	{
	case 1:
		buffer_res=getPrice(buffer);
		break;
	case 2:
		buffer_res=getInfo(buffer);
		break;

	}
	return buffer_res;
}

/*
	Get the price of the barcode and convert to cents
*/
string MyThread::getPrice(char buffer[])
{
	int s=0;
	unsigned char tmp;
	for (int i=0;i<4;i++)
	{
		tmp=buffer[i+3];
		s=s*256+tmp;
	}
	string price,centPrice;
	sql_Connector *contor=new sql_Connector();
	contor->start_Connect();
	contor->chooseDB("CG3002");
	Item *iFind= new Item();
	if (contor->search_from_barcode(s,iFind))
	{
		price=iFind->get_ItemPrice_toStr();
	}
	centPrice="";
	int l=price.length();
	for (int i=0;i<l;i++)
		if (isdigit(price[i]))
			centPrice+=price[i];
		else
		{
			i++;
			centPrice+=price[i];
			i++;
			if (i<l)
				centPrice+=price[i];
			else
				centPrice+='0';
		}
	delete contor;
	return centPrice;
}
string MyThread::getInfo(char buffer[])
{
	int s=0;
	unsigned char tmp;
	for (int i=0;i<4;i++)
	{
		tmp=buffer[i+3];
		s=s*256+tmp;
	}
	string result,price,name,quantity;
	sql_Connector *contor=new sql_Connector();
	contor->start_Connect();
	contor->chooseDB("CG3002");
	Item *iFind= new Item();
	if (contor->search_from_barcode(s,iFind))
	{
		price=iFind->get_ItemPrice_toStr();
		name=iFind->get_ItemName();
		quantity=iFind->get_ItemLocalStock();
	}

	result=name+price+quantity;
	delete contor;
	return result;
}

void MyThread::sendPID(QString pID_in)
{
	string pID_i=pID_in.toStdString();
	if (is_number(pID_i))
	{
		to_PriceDisplay = true;
		pID = boost::lexical_cast<int>(pID_i);
	}
}

bool MyThread::is_number(const std::string& s)
{
	return !s.empty() && std::find_if(s.begin(), 
        s.end(), [](char c) { return !isdigit(c); }) == s.end();
}

void MyThread::pid_new_info( void)
{
	to_PriceDisplay = true;
	// 0 means we will update to all price display
	pID=0;
}